home *** CD-ROM | disk | FTP | other *** search
/ Beginning Mac Programming / Beginning Mac Programming.bin / pc / Open Me for REALbasic 3 / REALbasic 3.2 / Goodies / 3rd Party Demos / 3rd Party Plugins / Misc / PEVocoder 1.0 (PPC) / PEVocodePlugin Source Code / MyNewMain.cp < prev    next >
Encoding:
Text File  |  2000-11-22  |  24.0 KB  |  858 lines

  1. /*
  2. -----
  3. Usage
  4. -----
  5.  
  6. There are two ways to run the vocoder.  If it is run without any
  7. command-line arguments (by clicking on its icon in Windows, for example)
  8. it will ask you for the values of the parameters.  The meanings of the
  9. parameters follow in the next section.
  10.  
  11. To specify tho parameters on the command-line, use the following syntax:
  12.  
  13.         vocoder [-q] [-N] [-b <band-count>] [-w <window-length] 
  14.                 [-o <window-overlap>] [-v <volume>] 
  15.                 <modulator-file> <carrier-file> <output-file>
  16.  
  17. (Note: this version also supports the version 1.0 syntax in order
  18. to be compatible with already existing front ends).
  19.  
  20. ----------
  21. Parameters
  22. ----------
  23.  
  24. A detailed explanation of what these parameters mean is in the next
  25. section.
  26.  
  27. Modulator filename (<modulator-file>)
  28.     the path to a sound file that contains the modulator waveform
  29.     (required).
  30.  
  31. Carrier filename (<carrier-file>)
  32.     the path to a sound file that contains the carrier waveform
  33.     (required).
  34.  
  35. Window length (-w <window-length>)
  36.     the number of samples that will be analyzed at a time, and must
  37.     be a power of two (defaults to about 1/15th of a second worth of
  38.     samples).
  39.  
  40. Window overlap (-o <window-overlap>)
  41.     the number of samples that the windows will be overlapped
  42.     (defaults to one half of the window-length).
  43.  
  44. Band count (-b <band-count>)
  45.     the number of frequency bands that the carrier will be modulated
  46.     with (defaults to 16).
  47.  
  48. Output volume (-v <volume>)
  49.     the volume the output will be scaled by (defaults to 1.0).
  50.  
  51. Output filename (output-file)
  52.     is the path to the output sound file (required).
  53.  
  54. These options are only available on the command-line:
  55.  
  56. -N    turns off normalizing the output with respect to the carrier. 
  57.  
  58. -q    turns off any displays.
  59.  
  60. The input sound files must be mono, 8- or 16-bit linear, uncompressed
  61. AIFF or WAVE files.  The output sound file will have the same format
  62. as the modulator (regardless of the file extension you give it).
  63. */
  64.  
  65. /******************************************************************************
  66.  * $Id: main.c,v 1.6 1999/03/16 06:55:59 emanuel Exp $
  67.  * Copyright (C) 1996-1998 Emanuel Borsboom <emanuel@zerius.com>
  68.  * Permission is granted to make any use of this code subject to the condition
  69.  * that all copies contain this notice and an indication of what has been
  70.  * changed.
  71.  *****************************************************************************/
  72.  
  73. #include <stdio.h>
  74. #include <stdlib.h>
  75. #include <stdarg.h>
  76. #include <math.h>
  77. #include <ctype.h>
  78. #include <limits.h>
  79. #include "config.h"
  80. #include "error.h"
  81. #include "wave.h"
  82. #include "fft.h"
  83.  
  84. //**********************************************
  85. //
  86. // Code added by E. Tejkowski-Nov. 2000
  87. //
  88. //**********************************************
  89.  
  90. #include <string.h>    // this and any other includes must come _before_ the "pragma mpwc on"!
  91. #ifndef WIN32
  92.     #include <MacMemory.h>
  93. #else
  94.     //static void DebugStr(unsigned char* p) {}
  95.     //static void Debugger() {}
  96. #endif
  97.  
  98. // REALbasic includes
  99. #if TARGET_CPU_68K
  100.     //#pragma mpwc on
  101. #endif
  102. #include "rb_plugin.h"    // this include must come _after_ the "pragma mpwc on"!
  103.  
  104. //**********************************************
  105. // End E. Tejkowski-Nov. 2000
  106. //**********************************************
  107.  
  108. typedef REAL (*COMPLEX_ARRAY)[2];
  109.  
  110. #define DEFAULT_WINDOW_TIME 15 /* 1/15th of a second */
  111.  
  112. static void vocode_window(REAL *modulator, COMPLEX_ARRAY carrier,
  113.                           COMPLEX_ARRAY output);
  114. static void vocoder(void);
  115. static void loop(WAVE_FILE *source, SAMPLE *dest, size_t length);
  116. static size_t read_zero(WAVE_FILE *source, SAMPLE *dest, size_t length);
  117. static void sample_to_complex_array(SAMPLE *sample_array,
  118.                                     COMPLEX_ARRAY complex_array,
  119.                                     size_t length, SAMPLE max_magnitude);
  120. static void sample_to_real_array(SAMPLE *sample_array, REAL *real_array,
  121.                                  size_t length, SAMPLE max_magnitude);
  122. static void complex_to_sample_array(COMPLEX_ARRAY complex_array,
  123.                                     SAMPLE *sample_array, size_t length,
  124.                                     SAMPLE max_magnitude, REAL volume);
  125. static void parse_args(int argc, char *argv[]);
  126. static void open_files(void);
  127. static void close_files(void);
  128. static void allocate_memory(void);
  129. static void free_memory(void);
  130. static int et_check_args(void);
  131. static int et_open_files(void);
  132.  
  133. char *prog_name;
  134.  
  135. static char *copyright = 
  136. "Zerius Vocoder 1.2 Copyright (C) 1996-1999 Emanuel Borsboom\n"
  137. "email: emanuel@zerius.com / web: http://zerius.com/vocoder/\n";
  138.  
  139. static char *modulator_filename, *carrier_filename, *output_filename;
  140. static BOOL got_window_length, got_window_overlap;
  141. static size_t window_length, window_overlap;
  142. static int band_count;
  143. static REAL volume;
  144. static BOOL quiet;
  145. static BOOL normalize;
  146.  
  147. static WAVE_FILE *modulator_file, *carrier_file, *output_file;
  148. static SAMPLE modulator_max_magnitude, carrier_max_magnitude,
  149.               output_max_magnitude;
  150. static INT modulator_length, modulator_rate;
  151.  
  152. static SAMPLE *modulator_sample_buffer, *carrier_sample_buffer,
  153.               *output_sample_buffer1, *output_sample_buffer2;
  154. static REAL *modulator;
  155. static COMPLEX_ARRAY looped_carrier, output;
  156.  
  157. static double *fft_c, *fft_s;
  158. static int *fft_rev;
  159. static void DoNothing(void);
  160. static void define_args(void);
  161.  
  162. static void vocode_window(REAL *modulator, COMPLEX_ARRAY carrier,
  163.                           COMPLEX_ARRAY output)
  164. {
  165.   int band_no, band_length, extra_band_length;
  166.  
  167.   band_length = window_length / (band_count * 2);
  168.   extra_band_length = window_length / 2 - band_length * (band_count - 1);
  169.  
  170.   realfftmag(modulator, window_length);
  171.   fft(carrier, window_length, fft_c, fft_s, fft_rev);
  172.   normalize_fft(carrier, window_length);
  173.   
  174.   for (band_no = 0; band_no < band_count; band_no++) {
  175.     int i, j, k, l;
  176.     REAL m, c;
  177.     
  178.     l = (band_no == band_count - 1) ? extra_band_length : band_length;
  179.  
  180.     m = 0; c = 0;
  181.     for (i = 0, j = band_no * band_length, k = window_length - j - 1;
  182.          i < l; i++, j++, k--)
  183.       {
  184.         if (normalize) {
  185.           REAL c1 = carrier[j][0]*carrier[j][0] + carrier[j][1]*carrier[j][1],
  186.                c2 = carrier[k][0]*carrier[k][0] + carrier[k][1]*carrier[k][1];
  187.           c += sqrt(c1) + sqrt(c2);
  188.         }
  189.         m += modulator[j];
  190.       }
  191.  
  192.     if (!normalize) c = 1.0;
  193.     if (c == 0) c = 0.0001;
  194.  
  195.     for (i = 0, j = band_no * band_length, k = window_length - j - 1;
  196.          i < l; i++, j++, k--) {
  197.       output[j][0] = carrier[j][0] * m / c;
  198.       output[j][1] = carrier[j][1] * m / c;
  199.       output[k][0] = carrier[k][0] * m / c;
  200.       output[k][1] = carrier[k][1] * m / c;
  201.     }
  202.   }
  203.  
  204.   invfft (output, window_length, fft_c, fft_s, fft_rev);
  205. }
  206.  
  207. static void start_status(void) 
  208. {
  209. }
  210.  
  211. static int update_status(INT frame_no, INT num_frames) {
  212.   int i, count = (frame_no + 1) * 56 / num_frames;
  213.   if (quiet) return 0;
  214.   /*printf("\r%3d%% |", (int)((frame_no + 1) * 100 / num_frames));*/
  215.   for (i = 0; i < count; ++i)
  216.       DoNothing();
  217.     /*putchar('*');*/
  218.   for (; i < 56; ++i)
  219.       DoNothing();
  220.     /*putchar(' ');*/
  221.   /*printf("| %ld/%ld", frame_no + 1, num_frames);*/
  222.   fflush(stdout);
  223.   return 0;    /* Return true to quit */
  224. }
  225.  
  226. static void finish_status(void) {
  227.   if (!quiet)
  228.     DoNothing();
  229.     /*printf("\n");*/
  230. }
  231.  
  232. static void vocoder(void)
  233. {
  234.   int i;
  235.   SAMPLE *output_old = output_sample_buffer1,
  236.          *output_new = output_sample_buffer2, *output_temp;
  237.   INT num_frames, frame_no;
  238.  
  239.   num_frames = (modulator_length - window_overlap) /
  240.                (window_length - window_overlap);
  241.   frame_no = 0;
  242.  
  243.   read_zero(modulator_file, modulator_sample_buffer, window_length);
  244.   loop(carrier_file, carrier_sample_buffer, window_length);
  245.   
  246.   sample_to_real_array(modulator_sample_buffer, modulator, window_length,
  247.                        modulator_max_magnitude);
  248.   sample_to_complex_array(carrier_sample_buffer, looped_carrier,
  249.                           window_length, carrier_max_magnitude);
  250.   
  251.   vocode_window(modulator, looped_carrier, output);
  252.   
  253.   complex_to_sample_array(output, output_old, window_length,
  254.                           output_max_magnitude, volume);
  255.   wave_write(output_file, output_old, window_length - window_overlap);
  256.  
  257.   for (i = 0; i < window_overlap; ++i)
  258.     {
  259.       modulator_sample_buffer[i] =
  260.         modulator_sample_buffer[window_length - window_overlap + i];
  261.       carrier_sample_buffer[i] =
  262.         carrier_sample_buffer[window_length - window_overlap + i];
  263.     }
  264.  
  265.   start_status();
  266.   
  267.   while (read_zero(modulator_file, modulator_sample_buffer +
  268.                    window_overlap, window_length - window_overlap))
  269.     {
  270.       if (update_status(frame_no, num_frames)) break;
  271.       
  272.       loop(carrier_file, carrier_sample_buffer + window_overlap,
  273.            window_length - window_overlap);
  274.       
  275.       sample_to_real_array(modulator_sample_buffer, modulator, window_length,
  276.                            modulator_max_magnitude);
  277.       sample_to_complex_array(carrier_sample_buffer, looped_carrier,
  278.                               window_length, carrier_max_magnitude);
  279.  
  280.       vocode_window(modulator, looped_carrier, output);
  281.  
  282.       complex_to_sample_array(output, output_new, window_length,
  283.                               output_max_magnitude, volume);
  284.  
  285.       for (i = 0; i < window_overlap; ++i)
  286.         { 
  287.           output_new[i] = (output_new[i] * (i / (double)window_overlap)) +
  288.                           (output_old[window_length - window_overlap + i] *
  289.                            ((window_overlap - i) / (double)window_overlap));
  290.         }
  291.  
  292.       wave_write(output_file, output_new, window_length - window_overlap);
  293.  
  294.       for (i = 0; i < window_overlap; ++i)
  295.         {
  296.           modulator_sample_buffer[i] =
  297.             modulator_sample_buffer[window_length - window_overlap + i];
  298.           carrier_sample_buffer[i] =
  299.             carrier_sample_buffer[window_length - window_overlap + i];
  300.         }
  301.  
  302.       output_temp = output_new;
  303.       output_new = output_old;
  304.       output_old = output_temp;
  305.  
  306.       ++frame_no;
  307.     }
  308.  
  309.   wave_write(output_file, output_old + window_length - window_overlap,
  310.              window_overlap);
  311.  
  312.   finish_status();
  313. }
  314.  
  315. static void loop(WAVE_FILE *source, SAMPLE *dest, size_t length)
  316. {
  317.   while (length > 0)
  318.     {
  319.       size_t n;
  320.  
  321.       n = wave_read(source, dest, length);
  322.       if (n < length) 
  323.         wave_seek(source, 0);
  324.  
  325.       dest += n;
  326.       length -= n;
  327.     }
  328. }
  329.  
  330. static size_t read_zero(WAVE_FILE *source, SAMPLE *dest, size_t length)
  331. {
  332.   size_t i, n = wave_read(source, dest, length);
  333.   for (i = n; i < length; ++i)
  334.     dest[i] = 0;
  335.   return n;
  336. }
  337.  
  338. static void sample_to_complex_array(SAMPLE *sample_array,
  339.                                     COMPLEX_ARRAY complex_array,
  340.                                     size_t length, SAMPLE max_magnitude)
  341. {
  342.   int i;
  343.   for (i = 0; i < length; ++i)
  344.     {
  345.       complex_array[i][0] = sample_array[i] / (REAL)max_magnitude;
  346.       complex_array[i][1] = 0;
  347.     }
  348. }
  349.  
  350. static void sample_to_real_array(SAMPLE *sample_array, REAL *real_array,
  351.                                  size_t length, SAMPLE max_magnitude)
  352. {
  353.   int i;
  354.   for (i = 0; i < length; ++i)
  355.     {
  356.       *real_array++ = *sample_array++ / (REAL)max_magnitude;
  357.     }
  358. }
  359.  
  360. static void complex_to_sample_array(COMPLEX_ARRAY complex_array,
  361.                                     SAMPLE *sample_array,
  362.                                     size_t length, SAMPLE max_magnitude,
  363.                                     REAL volume)
  364. {
  365.   int i;
  366.   for (i = 0; i < length; ++i)
  367.     {
  368.       REAL sample = complex_array[i][0] * volume;
  369.       if (sample < -1.0) sample = -1.0;
  370.       else if (sample > 1.0) sample = 1.0;
  371.       sample_array[i] = sample * max_magnitude;
  372.     }
  373. }
  374.  
  375. static void usage()
  376. {
  377.   /*printf("%s\n", copyright);
  378.   printf("usage: %s [-q] [-N] [-b <band-count>] [-w <window-length] "
  379.          "[-o <window-overlap>] [-v <volume>] "
  380.          "<modulator-file> <carrier-file> <output-file>\n", prog_name);*/
  381.   exit(1);
  382. }
  383.  
  384. static void prompt_user(const char *prompt, char *buffer, size_t length)
  385. {
  386.   printf("%s? ", prompt);
  387.   fgets(buffer, length, stdin);
  388. }
  389.  
  390. static void message_user(const char *fmt, ...)
  391. {
  392.   va_list ap;
  393.   va_start(ap, fmt);
  394.   vprintf(fmt, ap);
  395.   va_end(ap);
  396.   printf("\n");
  397. }
  398.  
  399. static void alert_user(const char *fmt, ...)
  400. {
  401.   va_list ap;
  402.   printf("! ");
  403.   va_start(ap, fmt);
  404.   vprintf(fmt, ap);
  405.   va_end(ap);
  406.   printf("\n");
  407. }
  408.  
  409. static void ask_user(const char *prompt, char *buffer, size_t length,
  410.              BOOL require_non_empty, BOOL require_number)
  411. {
  412.   char *p;
  413.   BOOL okay;
  414.   do
  415.     {
  416.       prompt_user(prompt, buffer, length);
  417.       okay = TRUE;
  418.       if (require_non_empty)
  419.         {
  420.       okay = FALSE;
  421.       p = buffer;
  422.       while (*p && *p != '\n') 
  423.         if (!isspace(*p++)) 
  424.           {
  425.             okay = TRUE;
  426.             break;
  427.           }
  428.       if (!okay) alert_user("You must enter a value.");
  429.     }
  430.       if (require_number) 
  431.         {
  432.           p = buffer;
  433.       while (*p && *p != '\n') 
  434.         {
  435.           if (!isdigit(*p) && *p != '.') 
  436.             {
  437.               alert_user("You may only enter digits.");
  438.           okay = FALSE;
  439.           break;
  440.             }
  441.           p++;
  442.         }
  443.         }
  444.     }
  445.   while (!okay);
  446.   p = strchr(buffer, '\n');
  447.   if (p) *p = '\0';
  448. }
  449.  
  450. static void ask_user_filename(const char *prompt, char *buffer, size_t length,
  451.                               BOOL require_existance)
  452. {
  453.   ask_user(prompt, buffer, length, TRUE, FALSE);
  454.   if (require_existance)
  455.     {
  456.       FILE *fp;
  457.       fp = fopen(buffer, "rb");
  458.       while (fp == NULL)
  459.         {
  460.       alert_user("Cannot open %s: %s", buffer, strerror(errno));
  461.           ask_user(prompt, buffer, length, TRUE, FALSE);
  462.           fp = fopen(buffer, "rb");
  463.     }
  464.       fclose(fp);
  465.     }
  466. }
  467.  
  468. static void parse_args(int argc, char *argv[])
  469. {
  470.   int i;
  471.   int PATH_MAX;
  472.   
  473.   PATH_MAX = 16;
  474.  
  475.   prog_name = argv[0];
  476.  
  477.   got_window_length = FALSE;
  478.   got_window_overlap = FALSE;
  479.   quiet = FALSE;
  480.   normalize = TRUE;
  481.   volume = 1.0;
  482.   band_count = 16;
  483.  
  484.   if (argc <= 1) 
  485.     {
  486.       char buf[16];
  487.       modulator_filename = (char*)error_malloc(PATH_MAX);//EJT
  488.       carrier_filename = (char*)error_malloc(PATH_MAX);//EJT
  489.       output_filename = (char*)error_malloc(PATH_MAX);//EJT
  490.       
  491.        
  492.       /* Stuff I Omitted by removing the following code 
  493.  
  494.       modulator_filename
  495.       carrier_filename
  496.       window_length = atoi(buf);
  497.       window_overlap = atoi(buf);
  498.       band_count = atoi(buf);
  499.       volume = atof(buf);
  500.       output_filename */
  501.  
  502.         ask_user_filename("Modulator filename (required)", modulator_filename, 
  503.                         PATH_MAX, TRUE);
  504.  
  505.       ask_user_filename("Carrier filename (required)", carrier_filename, 
  506.                         PATH_MAX, TRUE);
  507.  
  508.       ask_user("Window length (empty for default)", buf, sizeof(buf), 
  509.                FALSE, TRUE);
  510.       if (buf[0])  
  511.         {
  512.           window_length = atoi(buf);
  513.       got_window_length = TRUE;
  514.         }
  515.  
  516.       ask_user("Window overlap (empty for default)", buf, sizeof(buf), 
  517.            FALSE, TRUE);
  518.       if (buf[0])  
  519.         {
  520.           window_overlap = atoi(buf);
  521.       got_window_overlap = TRUE;
  522.         }
  523.  
  524.       ask_user("Band count (empty for default)", buf, sizeof(buf), 
  525.                FALSE, TRUE);
  526.       if (buf[0]) band_count = atoi(buf);
  527.  
  528.       ask_user("Output volume (empty for default)", buf, sizeof(buf), 
  529.                FALSE, TRUE);
  530.       if (buf[0]) volume = atof(buf);
  531.       ask_user_filename("Output filename (required)", output_filename, 
  532.                         PATH_MAX, FALSE);
  533.     } 
  534.   else if (argc == 7 &&
  535.       argv[1][0] != '-' && argv[2][0] != '-' &&
  536.       atoi(argv[3]) != 0 && atoi(argv[4]) != 0 && atoi(argv[5]) != 0 &&
  537.       argv[6][0] != '-')
  538.     {
  539.       modulator_filename = argv[1];
  540.       carrier_filename = argv[2];
  541.       window_length = atoi(argv[3]);
  542.       got_window_length = TRUE;
  543.       window_overlap = atoi(argv[4]);
  544.       got_window_overlap = TRUE;
  545.       band_count = atoi(argv[5]);
  546.       output_filename = argv[6];
  547.     }
  548.   else
  549.     {
  550.       for (i = 1; i < argc && argv[i][0] == '-'; ++i)
  551.         {
  552.           if (argv[i][1] == 'v' && i < argc - 1)
  553.             volume = atof(argv[++i]);
  554.           else if (argv[i][1] == 'b' && i < argc - 1)
  555.             band_count = atoi(argv[++i]);
  556.           else if (argv[i][1] == 'q')
  557.             quiet = TRUE;
  558.           else if (argv[i][1] == 'N')
  559.             normalize = FALSE;
  560.           else if (argv[i][1] == 'w' && i < argc - 1) {
  561.             window_length = atoi(argv[++i]);
  562.             got_window_length = TRUE;
  563.           }
  564.           else if (argv[i][1] == 'o' && i < argc - 1) {
  565.             window_overlap = atoi(argv[++i]);
  566.             got_window_overlap = TRUE;
  567.           }
  568.           else
  569.             usage();
  570.         }
  571.       
  572.       if (argc != i + 3)
  573.         usage();
  574.       
  575.       modulator_filename = argv[i++];
  576.       carrier_filename = argv[i++];
  577.       output_filename = argv[i++];
  578.     }
  579. }
  580.    
  581. static void open_files(void)
  582. {
  583.   WAVE_INFO wave_info;
  584.   carrier_file = wave_open(carrier_filename, &wave_info);
  585.   if (wave_info.channels != 1)
  586.     error("carrier must be mono (1 channel)");
  587.   carrier_max_magnitude = (1 << (wave_info.bits - 1)) - 1;
  588.   
  589.   modulator_file = wave_open(modulator_filename, &wave_info);
  590.   if (wave_info.channels != 1)
  591.     error("modulator must be mono (1 channel)");
  592.   modulator_max_magnitude = (1 << (wave_info.bits - 1)) - 1;
  593.   modulator_length = wave_info.length;
  594.   modulator_rate = wave_info.rate;
  595.   
  596.   output_file = wave_create(output_filename, &wave_info);
  597.   output_max_magnitude = (1 << (wave_info.bits - 1)) - 1;
  598. }
  599.  
  600. static int et_open_files(void)
  601. {
  602.   WAVE_INFO wave_info;
  603.   carrier_file = wave_open(carrier_filename, &wave_info);
  604.   if (wave_info.channels != 1)
  605.       return(-13);
  606.     //error("carrier must be mono (1 channel)");
  607.   carrier_max_magnitude = (1 << (wave_info.bits - 1)) - 1;
  608.   
  609.   modulator_file = wave_open(modulator_filename, &wave_info);
  610.   if (wave_info.channels != 1)
  611.     return(-14);
  612.     //error("modulator must be mono (1 channel)");
  613.   modulator_max_magnitude = (1 << (wave_info.bits - 1)) - 1;
  614.   modulator_length = wave_info.length;
  615.   modulator_rate = wave_info.rate;
  616.   
  617.   output_file = wave_create(output_filename, &wave_info);
  618.   output_max_magnitude = (1 << (wave_info.bits - 1)) - 1;
  619.   
  620.   return(1);
  621. }
  622.  
  623. static void check_args(void)
  624. {
  625.   if (!got_window_length)
  626.     window_length = ipow(2, ilog2(modulator_rate / DEFAULT_WINDOW_TIME));
  627.   if (!got_window_overlap)
  628.     window_overlap = window_length / 2;
  629.   
  630.   if (window_length < 2 || ipow(2, ilog2(window_length)) != window_length)
  631.     error("window-length must be > 1 and a power of two\n"
  632.           "(the closest power of two to the number you entered is %d)",
  633.           ipow(2, ilog2(window_length)));
  634.   if (window_overlap < 0 || window_overlap > window_length / 2)
  635.     error("window-overlap must be >= 0 and <= window-length/2");
  636.   if (band_count < 1 || band_count > window_length / 2)
  637.     error("band-count must be > 0 and <= window-length/2");
  638.  
  639.   if (!quiet)
  640.     DoNothing();
  641.     /*message_user("%s\nwindow-length: %d   window-overlap: %d   band-count: %d   "
  642.                  "volume: %.2f", copyright,
  643.                  window_length, window_overlap, band_count, volume);*/
  644. }
  645.  
  646. static int et_check_args(void)
  647. {
  648.  
  649.     int    err;
  650.     err = 1;
  651.  
  652.   if (!got_window_length)
  653.     window_length = ipow(2, ilog2(modulator_rate / DEFAULT_WINDOW_TIME));
  654.   if (!got_window_overlap)
  655.     window_overlap = window_length / 2;
  656.   
  657.   if (window_length < 2 || ipow(2, ilog2(window_length)) != window_length)
  658.     {err = -10;}
  659.     /*error("window-length must be > 1 and a power of two\n"
  660.           "(the closest power of two to the number you entered is %d)",
  661.           ipow(2, ilog2(window_length)));*/
  662.   if (window_overlap < 0 || window_overlap > window_length / 2)
  663.     {err = -11;}
  664.     /*error("window-overlap must be >= 0 and <= window-length/2");*/
  665.   if (band_count < 1 || band_count > window_length / 2)
  666.     {err = -12;}
  667.     /*error("band-count must be > 0 and <= window-length/2");*/
  668.  
  669.   //if (!quiet)
  670.     //DoNothing();
  671.     /*message_user("%s\nwindow-length: %d   window-overlap: %d   band-count: %d   "
  672.                  "volume: %.2f", copyright,
  673.                  window_length, window_overlap, band_count, volume);*/
  674.                  
  675.     return(err);
  676.                   
  677. }
  678. static void close_files(void)
  679. {
  680.   wave_close(output_file);
  681.   wave_close(modulator_file);
  682.   wave_close(carrier_file);
  683. }
  684.  
  685. static void allocate_memory(void)
  686. {
  687.   modulator_sample_buffer = (short*)error_malloc(sizeof(SAMPLE) * window_length);//EJT
  688.   carrier_sample_buffer = (short*)error_malloc(sizeof(SAMPLE) * window_length);//EJT
  689.   output_sample_buffer1 = (short*)error_malloc(sizeof(SAMPLE) * window_length);//EJT
  690.   output_sample_buffer2 = (short*)error_malloc(sizeof(SAMPLE) * window_length);//EJT
  691.   modulator = (double*)error_malloc(sizeof(REAL) * window_length);//EJT
  692.   looped_carrier = (COMPLEX_ARRAY)error_malloc(sizeof(REAL) * 2 * window_length);
  693.   output = (COMPLEX_ARRAY)error_malloc(sizeof(REAL) * 2 * window_length);
  694. }
  695.  
  696. static void free_memory(void)
  697. {
  698.   free(output);
  699.   free(looped_carrier);
  700.   free(modulator);
  701.   free(output_sample_buffer1);
  702.   free(output_sample_buffer2);
  703.   free(carrier_sample_buffer);
  704.   free(modulator_sample_buffer);
  705. }
  706.  
  707.  
  708. /*static int define_args(void)*/
  709. void define_args(void)
  710. /*(REALstring modulatorfilepath,REALstring carrierfile,REALstring outputfile, winlength,winoverlap,bandcount)*/
  711.     {
  712.      
  713.       got_window_length = FALSE;
  714.       got_window_overlap = FALSE;
  715.       quiet = FALSE;
  716.       normalize = TRUE;
  717.       volume = 1.0;
  718.       band_count = 16;
  719.   
  720.      /*(REALstring reduceString)
  721.      //char* str = REALCString(reduceString);*/
  722.      
  723.      modulator_filename = "modulator file";/*"modulator file";*/
  724.      carrier_filename = "carrier file";/*"carrier file";*/
  725.      
  726.      /*window_length = atoi(argv[3]);
  727.      got_window_length = TRUE;
  728.      window_overlap = atoi(argv[4]);
  729.      got_window_overlap = TRUE;*/
  730.      
  731.      /*band_count = atoi(argv[5]);*/
  732.      output_filename = "test2.aif";
  733.        
  734.      
  735.     /*
  736.     -N    turns off normalizing the output with respect to the carrier. 
  737.     -q    turns off any displays.
  738.     */
  739.     
  740.     /*volume = atof(argv[++i]);
  741.     quiet = TRUE;
  742.     normalize = FALSE;*/
  743.      
  744.       
  745.       /*return(1);*/
  746.     }
  747.  void DoNothing(void)
  748.  {
  749.  
  750.  }   
  751. /*int main(int argc, char *argv[])
  752.     {*/
  753.     //parse_args(argc, argv);
  754.     //define_args();/* This is my routine -EJT */
  755.     //open_files();
  756.     //check_args();/*do error returns to RB here */
  757.  
  758.     /* allocate_memory();
  759.     fft_create_arrays (&fft_c, &fft_s, &fft_rev, window_length);
  760.     vocoder();
  761.   
  762.     free_memory();
  763.     close_files();
  764.     return 0;
  765.     }*/
  766.  
  767. static int RBVocoderfunc (REALstring modulatorpath, REALstring carrierpath, REALstring targetpath, int windowlength, int windowoverlap, int bandcount )
  768. {
  769.  
  770.     int err;
  771.     err = 1;
  772.  
  773.   //define_args();/* Added routine - E.Tejkowski Nov 2000 */
  774.   //set windowlength and windowoverlap to '-1' to allow default values to run their course
  775.     if (windowlength==-1)
  776.      got_window_length = FALSE;
  777.      else
  778.      {
  779.       window_length = windowlength;
  780.       got_window_length = TRUE;
  781.      }
  782.      
  783.     if (windowoverlap==-1)
  784.      got_window_overlap = FALSE;
  785.     else
  786.      {
  787.       got_window_overlap = TRUE;
  788.       window_overlap = windowoverlap;
  789.      }
  790.  
  791.      quiet = FALSE;
  792.      normalize = TRUE;
  793.      volume = 1.0;
  794.  
  795.      if (bandcount<=0)
  796.      {
  797.      band_count = 16;
  798.      }
  799.      else
  800.      {
  801.      band_count = bandcount;
  802.      }
  803.   
  804.      /*(REALstring reduceString)
  805.      //char* str = REALCString(reduceString);*/
  806.      
  807.     modulator_filename = REALCString(modulatorpath);//"modulator file";/*"modulator file";*/
  808.     carrier_filename = REALCString(carrierpath);//"carrier file";/*"carrier file";*/
  809.     output_filename = REALCString(targetpath);//"test2.aif";
  810.          
  811.     /*window_length = atoi(argv[3]);
  812.     got_window_length = TRUE;
  813.     window_overlap = atoi(argv[4]);
  814.     got_window_overlap = TRUE;*/
  815.     /*band_count = atoi(argv[5]);*/
  816.  
  817.     err = et_open_files();/*do error returns to RB here */
  818.     if (err<=0)
  819.         return err;
  820.         
  821.     et_check_args();/*do error returns to RB here */
  822.     if (err<=0)
  823.         return err;
  824.  
  825.     allocate_memory();
  826.     fft_create_arrays (&fft_c, &fft_s, &fft_rev, window_length);
  827.     vocoder();
  828.   
  829.     free_memory();
  830.     close_files();
  831.  
  832.       //return 1;
  833.       return err;
  834. }
  835.  
  836. //-----------------------
  837. // Add global RB methods
  838. //-----------------------
  839.  
  840.  
  841. static REALmethodDefinition pluginMethodArray[] = {
  842.     { (REALproc) RBVocoderfunc, REALnoImplementation, "PEVocode(modulatorpath as string, carrierpath as string,targetpath as string, windowlength as integer, windowoverlap as integer, bandcount as integer ) as Integer" },
  843.  
  844. };
  845.  
  846.  
  847.  
  848. void PluginEntry (void)
  849. {
  850.  
  851.  
  852.     // Use this code to make your global RB methods known to RB:
  853.     for (int i = 0; i < sizeof(pluginMethodArray) / sizeof(REALmethodDefinition); ++i) {
  854.         REALRegisterMethod (&pluginMethodArray[i]);
  855.     }
  856.  
  857. }
  858.